package com.example.helloword.jcip.chap5.chap516;

import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;

/**
 * 上一个版本中if 中非原子操作存在重复计算的可能性
 *
 * @author Brian Goetz and Tim Peierls
 */
public class Memoizer4Last<A, V> implements Computable<A,V> {
    //存放的是计算过程
    private final Map<A, Future<V>> cache = new ConcurrentHashMap<A, Future<V>>();
    private final Computable<A, V> c;

    public Memoizer4Last(Computable<A, V> c) {
        this.c = c;
    }

    @Override
    public V compute(A arg) throws InterruptedException {
        Future<V> f = cache.get(arg);
        //problem-这个非原子操作-存在重复进行计算的可能性
        if (f == null) {
            Callable<V> eval = new Callable<V>() {
                @Override
                public V call() throws Exception {
                    return c.compute(arg);
                }
            };

            FutureTask<V> ft = new FutureTask<>(eval);
//            f = ft;
//            cache.put(arg, ft);
            f = cache.putIfAbsent(arg, ft);
            if (f == null) { //说明第一次前面没有这个计算过程
                f = ft;
                new Thread(ft).run(); //这里改成异步调用
            }
            //如果不为空说明有计算正在进行中
        }


        try {
            return f.get();
        } catch (ExecutionException e) {
            throw (InterruptedException)e.getCause();
        }

    }
}
